package com.xh.bussiness.teachbook.util;

import com.aspose.words.*;
import com.aspose.words.net.System.Data.DataRelation;
import com.aspose.words.net.System.Data.DataRow;
import com.aspose.words.net.System.Data.DataSet;
import com.aspose.words.net.System.Data.DataTable;
import com.xh.bussiness.exam.model.UserErrorQuestion;
import com.xh.bussiness.exam.service.IUserErrorQuestionService;
import com.xh.bussiness.teachbook.bean.dto.*;
import com.xh.bussiness.teachbook.constant.TeachingBookConstant;
import com.xh.bussiness.tiku.bean.dto.QuestionDto;
import com.xh.bussiness.tiku.service.IQuestionService;
import com.xh.bussiness.tiku.util.QuestionUtils;
import com.xh.core.handler.MergeFieldTextbookHtmlHandle;
import com.xh.core.util.FileUtils;
import com.xh.core.util.OfficeUtils;
import com.xh.core.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.*;
import java.util.List;

/**
 * <p>
 *
 * </p>
 *
 * @author Pitt zhang
 * @since 2019/12/28
 */
@Component
public class TeachingBookUtils {

    private static Logger log = LoggerFactory.getLogger(TeachingBookUtils.class);

    private static IUserErrorQuestionService _userErrorQuestionService;

    private static IQuestionService _questionService;

    @Autowired
    private IUserErrorQuestionService userErrorQuestionService;
    @Autowired
    private IQuestionService questionService;

    @PostConstruct
    public void init() {
        _userErrorQuestionService = userErrorQuestionService;
        _questionService = questionService;
    }

    static {
        try {
            InputStream wordsLicense = OfficeUtils.class.getClassLoader().getResourceAsStream("aspose.words.license.xml");// 凭证文件
            InputStream slidesLicense = OfficeUtils.class.getClassLoader().getResourceAsStream("aspose.slides.license.xml");// 凭证文件
            InputStream cellsLicense = OfficeUtils.class.getClassLoader().getResourceAsStream("aspose.cells.license.xml");// 凭证文件

            com.aspose.slides.License slidesLic = new com.aspose.slides.License();
            slidesLic.setLicense(slidesLicense);
            com.aspose.words.License wordsLic = new com.aspose.words.License();
            wordsLic.setLicense(wordsLicense);
            com.aspose.cells.License cellsLic = new com.aspose.cells.License();
            cellsLic.setLicense(cellsLicense);

            //com.aspose.words.FontSettings.getDefaultInstance().setFontsFolder("/Users/david/Documents/Fonts", false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 讲义导出word
     *
     * @param teachingBookDto
     * @param request
     * @return
     */
    public static String exportTeachingBook(Integer downloadType, TeachingBookDto teachingBookDto, HttpServletRequest request) throws Exception {
        String template = TeachingBookUtils.class.getResource("/").getFile() + "templates/teachingBook/TeachingBookTempleate.docx";
        //windows Linux 不同路径问题，需要进行路径截取
        if (System.getProperty("file.separator").equals("\\")) {
            template = template.substring(1, template.length());
        }
        //提取练习模块单独处理
        //练习总分数
        Integer practiceTotalScore = 0;
        //练习总用时
        Long practiceUseTime = 0l;
        String year = "";
        String month = "";
        String day = "";
        List<TeachingBookPracticeContentDto> practiceContentDtos = null;
        TeachingBookModuleDto practiceModule = teachingBookDto.getModules().stream().filter(item -> item.getType().equals(TeachingBookConstant.TeachingBookTemplate.PRACTICE)).findFirst().get();
        if (practiceModule != null) {
            TeachingBookPracticeDto practiceDto = practiceModule.getTeachingBookPracticeRequest();
            if (practiceDto != null) {
                practiceTotalScore = practiceDto.getTotalScore() == null ? 0 : practiceDto.getTotalScore();
                practiceUseTime = practiceDto.getUseTime() == null ? 0l : practiceDto.getUseTime();
                year = practiceDto.getYear() == null ? "" : practiceDto.getYear().toString();
                month = practiceDto.getMonth() == null ? "" : practiceDto.getMonth().toString();
                day = practiceDto.getDay() == null ? "" : practiceDto.getDay().toString();
                practiceContentDtos = practiceDto.getContentDtos();
            }
        }
        String startTime = teachingBookDto.getStartTime() == null ? "" : teachingBookDto.getStartTime();
        String endTime = teachingBookDto.getEndTime() == null ? "" : teachingBookDto.getEndTime();
        //封装固定属性和值
        String[] fieldNames = new String[]{
                "stuName", "schoolName",
                "gradeName", "number",
                "subject", "teacherName",
                "schoolDate", "schoolTime",
                "topicName", "totalScore",
                "useTime", "teacherName",
                "year", "month", "day"
        };
        String[] fieldValues = new String[]{
                teachingBookDto.getRefName(), teachingBookDto.getSchoolName(),
                teachingBookDto.getGradeName(), teachingBookDto.getNumber() == null ? "" : teachingBookDto.getNumber().toString(),
                teachingBookDto.getSubjectName(), teachingBookDto.getTeacherName(),
                teachingBookDto.getSchoolTime() == null ? "" : teachingBookDto.getSchoolTime(), startTime + "-" + endTime,
                teachingBookDto.getTopic() == null ? "" : teachingBookDto.getTopic(), practiceTotalScore.toString(),
                practiceUseTime.toString(), teachingBookDto.getTeacherName() == null ? "" : teachingBookDto.getTeacherName(),
                year, month, day
        };
        //实例化word模板
        Document doc = new Document(template);
        //处理html内容
        doc.getMailMerge().setFieldMergingCallback(new MergeFieldTextbookHtmlHandle(1, "content"));
        doc.getMailMerge().execute(fieldNames, fieldValues);

        DataSet dataSet = new DataSet();

        //插入备课模块数据
        DataTable modulesDataTable = new DataTable("ModuleList");
        modulesDataTable.getColumns().add("id");
        modulesDataTable.getColumns().add("moduleTitle");

        //插入备课模块明细数据
        DataTable moduleDetailDataTable = new DataTable("ModuleDetailList");
        moduleDetailDataTable.getColumns().add("id");
        moduleDetailDataTable.getColumns().add("moduleId");
        moduleDetailDataTable.getColumns().add("contentTypeName");
        moduleDetailDataTable.getColumns().add("orderNo");
        moduleDetailDataTable.getColumns().add("content");
        moduleDetailDataTable.getColumns().add("question");

        //插入备课练习模块数据
        DataTable practiceDetailDataTable = new DataTable("PracticeDetailList");
        practiceDetailDataTable.getColumns().add("id");
        practiceDetailDataTable.getColumns().add("practiceContentTypeName");
        practiceDetailDataTable.getColumns().add("orderNo");
        practiceDetailDataTable.getColumns().add("content");
        practiceDetailDataTable.getColumns().add("score");
        practiceDetailDataTable.getColumns().add("practiceQuestion");

        Map<String, List<String>> questionMap = new HashMap<>();
        DataRow row = null;
        if (!CollectionUtils.isEmpty(teachingBookDto.getModules())) {
            //渲染备课模块数据
            int moduleOrder = 1;
            for (int i = 0; i < teachingBookDto.getModules().size(); i++) {
                TeachingBookModuleDto moduleDto = teachingBookDto.getModules().get(i);
                if (moduleDto.getType().equals(TeachingBookConstant.TeachingBookTemplate.PRACTICE)) {
                    continue;
                }

                List<TeachingBookModuleDetailDto> moduleDetailDtos = moduleDto.getTeachingBookModuleDetailRequest();
                if (CollectionUtils.isEmpty(moduleDetailDtos)) {
                    continue;
                }

                row = modulesDataTable.newRow();
                row.set("id", moduleDto.getId());
                row.set("moduleTitle", NumberUtil.numberToChinese(moduleOrder) + "、" + moduleDto.getName());
                modulesDataTable.getRows().add(row);

                Integer orderNo = 1;
                for (int j = 0; j < moduleDetailDtos.size(); j++) {
                    TeachingBookModuleDetailDto detailDto = moduleDetailDtos.get(j);
                    DataRow row1 = moduleDetailDataTable.newRow();
                    row1.set("id", detailDto.getId());
                    row1.set("moduleId", detailDto.getTeachingBookModuleId());

                    //1.错题;2.变试题;3.普通试题;4.考点分析;5.文本/段落;6.思维导图;7.练习;8.自编试题;9.相似题
                    if (detailDto.getContentType().equals(1)) {
                        UserErrorQuestion userErrorQuestion = _userErrorQuestionService.getById(detailDto.getResourceId());
                        if (userErrorQuestion != null) {
                            QuestionDto question = _questionService.getQuestion(userErrorQuestion.getQuestionId(), null, true,false,false,false,false);
                            if (question == null) {
                                continue;
                            }
                            if (question.getSourceFrom() != null && question.getSourceFrom().equals(1)) {
                                //自编题处理
                                String questionHtml = "";
                                if (downloadType.equals(1) && question != null) {
                                    questionHtml = QuestionUtils.getQuestionHtml(question, true, true, true,true);
                                } else if (question != null) {
                                    questionHtml = QuestionUtils.getQuestionHtml(question, true,false, false, false);
                                }
                                if (!StringUtils.isEmpty(questionHtml)) {
                                    row1.set("content", questionHtml);
                                }
                            }else {
                                row1.set("orderNo", orderNo + "、");
                                row1.set("question", "<" + userErrorQuestion.getQuestionId() + ">");
                                //添加试题id
                                addQuestionToMap(questionMap, userErrorQuestion.getSubjectId(), userErrorQuestion.getQuestionId());
                            }
                            orderNo++;
                        }
                    } else if (detailDto.getContentType().equals(2) || detailDto.getContentType().equals(3)
                            || detailDto.getContentType().equals(9)) {
                        QuestionDto question = _questionService.getQuestion(detailDto.getResourceId(), null, true,false,false,false,false);
                        if (question == null) {
                            continue;
                        }
                        if (question.getSourceFrom() != null && question.getSourceFrom().equals(1)) {
                            //自编题处理
                            String questionHtml = "";
                            if (downloadType.equals(1) && question != null) {
                                questionHtml = QuestionUtils.getQuestionHtml(question, true, true,true, true);
                            } else if (question != null) {
                                questionHtml = QuestionUtils.getQuestionHtml(question, true,false, false, false);
                            }
                            if (!StringUtils.isEmpty(questionHtml)) {
                                row1.set("content", questionHtml);
                            }
                        }else {
                            row1.set("orderNo", orderNo + "、");
                            row1.set("question", "<" + detailDto.getResourceId() + ">");
                            //添加试题id
                            addQuestionToMap(questionMap, detailDto.getSubject(), detailDto.getResourceId());
                        }
                        orderNo++;
                    } else if (detailDto.getContentType().equals(8)) {
                        //TODO 自编试题
                        //downloadType =1 老师 2学生
                        QuestionDto question = _questionService.getQuestion(detailDto.getResourceId(), null,true,false,false,false,false);
                        String questionHtml = "";
                        if (downloadType.equals(1) && question != null) {
                            questionHtml = QuestionUtils.getQuestionHtml(question, true, true, true, true);
                        } else if (question != null) {
                            questionHtml = QuestionUtils.getQuestionHtml(question, true, false, false, false);
                        }
                        if (!StringUtils.isEmpty(questionHtml)) {
                            row1.set("orderNo", orderNo + "、");
                            row1.set("content", questionHtml);
                        }
                        orderNo++;
                    } else if (detailDto.getContentType().equals(6)) {
                        row1.set("content", "<img src='" + detailDto.getMindMapImgPath() + "' />");
                    } else {
                        row1.set("content", detailDto.getContent());
                    }
                    moduleDetailDataTable.getRows().add(row1);
                }
                moduleOrder++;
            }
        }else{
            //无模块插入空行
            DataRow row1 = moduleDetailDataTable.newRow();
            moduleDetailDataTable.getRows().add(row1);
        }
        //处理练习内容
        if (!CollectionUtils.isEmpty(practiceContentDtos)) {
            int orderNo = 1;
            for (TeachingBookPracticeContentDto practiceContentDto : practiceContentDtos) {
                row = practiceDetailDataTable.newRow();
                if (practiceContentDto.getContentType().equals(TeachingBookConstant.PracticeContentType.QUESTION)) {
                    QuestionDto question = _questionService.getQuestion(practiceContentDto.getQuestionId(), null, true,false,false,false,false);
                    if (question == null) {
                        continue;
                    }
                    if (question.getSourceFrom() != null && question.getSourceFrom().equals(1)) {
                        //自编题处理
                        String questionHtml = "";
                        if (downloadType.equals(1) && question != null) {
                            questionHtml = QuestionUtils.getQuestionHtml(question, true, true, true, true);
                        } else if (question != null) {
                            questionHtml = QuestionUtils.getQuestionHtml(question, true, false, false, false);
                        }
                        if (!StringUtils.isEmpty(questionHtml)) {
                            row.set("content", questionHtml);
                        }
                    }else {
                        row.set("orderNo", orderNo + "、");
                        row.set("score", "(" + practiceContentDto.getScore() + "分)");
                        row.set("practiceQuestion", "<" + practiceContentDto.getQuestionId() + ">");
                        //添加试题id
                        addQuestionToMap(questionMap, practiceContentDto.getSubject(), practiceContentDto.getQuestionId());
                    }
                    orderNo++;
                } else {
                    row.set("content", practiceContentDto.getContent());
                }
                practiceDetailDataTable.getRows().add(row);
            }
        }else{
            //无模块插入空行
            row = practiceDetailDataTable.newRow();
            practiceDetailDataTable.getRows().add(row);
        }

        dataSet.getTables().add(modulesDataTable);
        dataSet.getTables().add(moduleDetailDataTable);
        dataSet.getTables().add(practiceDetailDataTable);
        //设置层级关系
        String exportPath = request.getSession().getServletContext().getRealPath("/") + "export/" + FileUtils.createRandomFilename() + ".docx";
        dataSet.getRelations().add(new DataRelation("ModuleDetailList", modulesDataTable.getColumns().get("id"), moduleDetailDataTable.getColumns().get("moduleId")));

        doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS);
        doc.getMailMerge().executeWithRegions(dataSet);
        FileUtils.createFileDirectory(exportPath);

        //定位段落中图片位置垂直居中显示
        int lineHeight=-5;
        NodeCollection childNodes = doc.getChildNodes(NodeType.PARAGRAPH, true);
        for (int i = 0; i < childNodes.getCount(); i++) {
            //删除空行
            Paragraph paragraph = (Paragraph)childNodes.get(i);
            if (!paragraph.hasChildNodes()) {
                paragraph.remove();
            }
            NodeCollection collection = paragraph.getChildNodes(NodeType.SHAPE,true);
            for (int j = 0; j < collection.getCount(); j++) {
                Shape  shape = (Shape)collection.get(j);
                shape.getFont().setPosition(- shape.getHeight()/2-lineHeight);
            }
        }

        doc.save(exportPath, com.aspose.words.SaveFormat.DOCX);

        //下载箐优网试题
        List<Map<String, String>> quesFilePathList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(questionMap)) {
            questionMap.forEach((k, v) -> {
                v.forEach(quesId -> {
                    try {
                        Map<String, String> quesFileMap = new HashMap<>();
                        String filePath = _questionService.downloadQuestion(downloadType, k, quesId, request);
                        quesFileMap.clear();
                        quesFileMap.put("fileName", quesId);
                        quesFileMap.put("filePath", filePath);
                        quesFilePathList.add(quesFileMap);
                    } catch (Exception e) {
                        log.error("downloadQuestion have error:" + e.getMessage());
                    }
                });
            });
        }
        //合并试题word
        if (!CollectionUtils.isEmpty(quesFilePathList)) {
            Map<String, String> mergeFiles = new LinkedHashMap<>();
            for (Map<String, String> quesFileMap : quesFilePathList) {
                //todo 获取文件名，替换word
                String fileName = quesFileMap.get("fileName");
                String filePath = quesFileMap.get("filePath");
                if (!StringUtils.isEmpty(fileName) && !StringUtils.isEmpty(filePath)) {
                    mergeFiles.put(fileName, filePath);
                }
            }
            String newExportPath = request.getSession().getServletContext().getRealPath("/") + "export/" + FileUtils.createRandomFilename() + ".docx";
            OfficeUtils.wordsInsert(exportPath, newExportPath, mergeFiles);
            //删除原文件
            FileUtils.delFile(exportPath);
            return newExportPath;
        }
        return exportPath;
    }

    private static void addQuestionToMap(Map<String, List<String>> questionMap, String subject, String questionId) {
        if (!StringUtils.isEmpty(subject) && !StringUtils.isEmpty(questionId)) {
            if (questionMap.containsKey(subject)) {
                List<String> quesIds = questionMap.get(subject);
                quesIds.add(questionId);
                questionMap.put(subject, quesIds);
            } else {
                List<String> quesIds = new ArrayList<>();
                quesIds.add(questionId);
                questionMap.put(subject, quesIds);
            }
        }
    }

}
